package com.model;

import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import java.util.*;
import java.lang.Math;

public class Draw{   
    public static void main(String[] args) {   
        new DrawSee();
    }   
}   

class DrawSee extends JFrame {
	Five five=new Five();
	Scanner scanner=new Scanner(System.in);
    
    private static final int x0= 50;
    private static final int y0 = 100;
    private static final int width = 3;
    private static final int hight = 3;
	private static final int pix = 30;
    
    
    private Graphics jg;
    
    
    
    private Color rectColor = new Color(0xF8CB19);
    
    /**
     * DrawSee���췽��
     */
    public DrawSee() {
        Container p = getContentPane();
        setBounds(100, 100, 600, 600);
        setVisible(true);
        p.setBackground(rectColor);
        setLayout(null);   
        setResizable(false);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   
		
		final int locate[]={1,1};
		final int target[]={-1,-1};
        
        try {
            Thread.sleep(500);
        } catch (Exception e) {
            e.printStackTrace();
        }        

        // ��ȡר�������ڴ��ڽ����ϻ�ͼ�Ķ���
        jg =  this.getGraphics();
		// ������Ϸ����
        paintComponents();

		// ���������¼����������ʱ����
        this.addMouseListener(new MouseAdapter() {
            
            // ����������¼���Ӧ����
          
            public void mouseClicked(MouseEvent e) {
                              
                //��ȡ���������һ���x��y����
                int xm = e.getX(), ym = e.getY();
				int x=(xm-x0+pix/2)/pix;
				int y=(ym-y0+pix/2)/pix;
				if(x<0||x>3||y<0||y>3){
					return;
				}
				if(five.tree.map.zi[x][y]==-1){
					locate[0]=x;
					locate[1]=y;
				}
				if(five.tree.map.zi[x][y]==0){
					target[0]=x;
					target[1]=y;
					if(Math.pow(locate[0]-target[0],2)+Math.pow(locate[1]-target[1],2)==1){
						
						five.move(locate[0],locate[1],target[0],target[1]);
						paintComponents();
					}
				}
				
				
				if(Math.abs(five.tree.map.localscore)>5){
					System.out.println("game over");
				}
            }
        });
        
    }
    
    
    
    public void paintComponents() {
        try {
            

            jg.setColor(Color.red);
            
            // ���������ο�
            jg.fillRect(0, 0, 1000, 1000);
            
			 jg.setColor(Color.black);
            for(int i = 0; i < width+1; i ++) {
                // ���Ƶ�i����ֱ��
                jg.drawLine(x0+i*pix,y0,x0+i*pix,y0+hight*pix);
                
                // ���Ƶ�i��ˮƽ��
                jg.drawLine(x0,y0+i*pix,x0+width*pix,y0+i*pix);
                
            }
			for(int i=0;i<4;i++){
				for(int j=0;j<4;j++){
					if(five.tree.map.zi[i][j]==1){
						jg.setColor(Color.black);
						jg.fillOval(x0+i*pix-pix/2,y0+j*pix-pix/2,pix,pix);
					}else if(five.tree.map.zi[i][j]==-1){
						jg.setColor(Color.white);
						jg.fillOval(x0+i*pix-pix/2,y0+j*pix-pix/2,pix,pix);
					}
				}
			}
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
   
}

class Map{
	int heicount=6;
	int baicount=6;
	int zi[][]=new int[4][4];
	long localscore=0;
	int next[][]=new int[48][4];
	int nextcount=0;
	Map(){
		int i,j;
		for(i=0;i<4;i++){
			for(j=0;j<4;j++){
				zi[i][j]=0;
			}
		}
		zi[0][0]=1;zi[0][1]=1;zi[0][2]=1;zi[0][3]=1;zi[1][0]=1;zi[1][3]=1;
		zi[3][0]=-1;zi[3][1]=-1;zi[3][2]=-1;zi[3][3]=-1;zi[2][0]=-1;zi[2][3]=-1;
	}
	void move(int x1,int y1,int x2,int y2){
		zi[x2][y2]=zi[x1][y1];
		zi[x1][y1]=0;
		int color=zi[x2][y2];
		
		int he=0,xkong=0,xhei=0,xbai=0,kongcount=0,hcount=0,bcount=0;
		for(int i=0;i<=3;i++){
			he+=zi[i][y2];
			if(zi[i][y2]==0) {xkong=i;kongcount++;}
			else if(zi[i][y2]==-1) {xbai=i;bcount++;}
			else if(zi[i][y2]==1) {xhei=i;hcount++;}
		}
		if(Math.abs(he)==1&&kongcount==1&&(xkong==0||xkong==3)){
			if(hcount==1&&color==-1&&Math.abs(xhei-xkong)!=2){
				heicount--;
				zi[xhei][y2]=0;
			}else if(bcount==1&&color==1&&Math.abs(xbai-xkong)!=2){
				baicount--;
				zi[xbai][y2]=0;
			}
		}
		
		int ykong=0,yhei=0,ybai=0;
		he=0;kongcount=0;hcount=0;bcount=0;
		for(int j=0;j<=3;j++){
			he+=zi[x2][j];
			if(zi[x2][j]==0) {ykong=j;kongcount++;}
			else if(zi[x2][j]==-1) {ybai=j;bcount++;}
			else if(zi[x2][j]==1) {yhei=j;hcount++;}
		}
		if(Math.abs(he)==1&&kongcount==1&&(ykong==0||ykong==3)){
			if(hcount==1&&color==-1&&Math.abs(yhei-ykong)!=2){
				heicount--;
				zi[x2][yhei]=0;
			}else if(bcount==1&&color==1&&Math.abs(ybai-ykong)!=2){
				baicount--;
				zi[x2][ybai]=0;
			}
		}
		
	}
	void setnext(){
		nextcount=0;
		int i,j,m,n;
		for(i=0;i<4;i++){
			for(j=0;j<4;j++){
				if(zi[i][j]==0) continue;
						if(i-1>=0&&zi[i-1][j]==0){
							next[nextcount][0]=i;
							next[nextcount][1]=j;
							next[nextcount][2]=i-1;
							next[nextcount][3]=j;
							nextcount++;
						}
						if(i+1<=3&&zi[i+1][j]==0){
							next[nextcount][0]=i;
							next[nextcount][1]=j;
							next[nextcount][2]=i+1;
							next[nextcount][3]=j;
							nextcount++;
						}
						if(j-1>=0&&zi[i][j-1]==0){
							next[nextcount][0]=i;
							next[nextcount][1]=j;
							next[nextcount][2]=i;
							next[nextcount][3]=j-1;
							nextcount++;
						}
						if(j+1<=3&&zi[i][j+1]==0){
							next[nextcount][0]=i;
							next[nextcount][1]=j;
							next[nextcount][2]=i;
							next[nextcount][3]=j+1;
							nextcount++;
						}
				}
				
			}
	}


	void setlocalscore(){
		
		localscore=heicount-baicount;
	}
}

class Tree{
	int deep=5;
	int xy[]=new int[4];
	int besttree[]=new int[4];
	Map map=new Map();
	long score=0;
//	int ismax;
	Tree[] child=new Tree[48];
	int childcount=0;

	void sheng(int n){
		childcount=0;
		if(n>deep||Math.abs(map.localscore)>3){
			return;
		}
		int i=0,color=0,j=0,k=0;
		if(n%2==0) color=1;
		else color=-1;
		for(i=0;i<map.nextcount;i++){
			if(color!=map.zi[map.next[i][0]][map.next[i][1]]) continue;
			child[childcount]=new Tree();
			child[childcount].xy[0]=map.next[i][0];
			child[childcount].xy[1]=map.next[i][1];
			child[childcount].xy[2]=map.next[i][2];
			child[childcount].xy[3]=map.next[i][3];

			for(j=0;j<4;j++){
				for(k=0;k<4;k++){
					child[childcount].map.zi[j][k]=map.zi[j][k];
				}
			}
			child[childcount].map.heicount=map.heicount;
			child[childcount].map.baicount=map.baicount;
		
			child[childcount].map.move(map.next[i][0],map.next[i][1],map.next[i][2],map.next[i][3]);
			child[childcount].map.setnext();
			child[childcount].map.setlocalscore();
			child[childcount].sheng(n+1);
			childcount++;
		}
	}


	long setscore(int n){
		long m=0,k=0;
		int i=0;
		if(n>deep||Math.abs(map.localscore)>3||childcount==0){
			score=map.localscore;
			return map.localscore;
		}
		m=child[0].setscore(n+1);
		besttree[0]=child[0].xy[0];
		besttree[1]=child[0].xy[1];
		besttree[2]=child[0].xy[2];
		besttree[3]=child[0].xy[3];
		if(n%2==0){
			for(i=1;i<childcount;i++){
				if((k=child[i].setscore(n+1))>m){
					m=k;
					besttree[0]=child[i].xy[0];
					besttree[1]=child[i].xy[1];
					besttree[2]=child[i].xy[2];
					besttree[3]=child[i].xy[3];
				}
			}
		}else{
			for(i=1;i<childcount;i++){
				if((k=child[i].setscore(n+1))<m){
					m=k;
					besttree[0]=child[i].xy[0];
					besttree[1]=child[i].xy[1];
					besttree[2]=child[i].xy[2];
					besttree[3]=child[i].xy[3];
				}
			}
		}
		score=m;
		return score;
	}
}

class Five{
	Tree tree=new Tree();
	int aixy[]=new int[4];

	Five(){

	}
	void move(int x1,int y1,int x2,int y2){
		tree.map.move(x1,y1,x2,y2);
		tree.map.setlocalscore();
		tree.map.setnext();
		tree.sheng(0);
		tree.setscore(0);
		aixy[0]=tree.besttree[0];
		aixy[1]=tree.besttree[1];
		aixy[2]=tree.besttree[2];
		aixy[3]=tree.besttree[3];
		tree.map.move(aixy[0],aixy[1],aixy[2],aixy[3]);
	}
}

